package com.echo.service;

import com.echo.dao.UserDao;
import com.echo.entity.User;
import com.echo.util.BCryptUtil;
import com.echo.util.BusinessException;
import com.echo.util.JdbcUtils;
import com.echo.util.StringUtils;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

public class UserService {

    private static final Logger logger = Logger.getLogger(UserService.class.getName());
    // 依赖DAO层
    private UserDao userDao = new UserDao();

    // 1. 注册功能
    public void register(User user, String confirmPwd) throws BusinessException {
        logger.info("===== 开始用户注册处理 ====");
        logger.info("接收到注册用户信息: " + user.getUsername() + ", " + user.getEmail());
        
        // 基础参数校验
        if (StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getPassword()) || StringUtils.isEmpty(user.getEmail())) {
            logger.warning("注册失败：用户名、密码或邮箱为空");
            throw new BusinessException("用户名、密码、邮箱不能为空！");
        }
        if (user.getPassword().length() < 6) {
            logger.warning("注册失败：密码长度不足6位");
            throw new BusinessException("密码长度不能少于6位！");
        }
        if (!user.getPassword().equals(confirmPwd)) {
            logger.warning("注册失败：两次输入的密码不一致");
            throw new BusinessException("两次输入的密码不一致！");
        }
        
        // 用户名格式验证：只能包含中文和英文字母
        if (!StringUtils.isValidUsername(user.getUsername())) {
            logger.warning("注册失败：用户名包含非法字符" + user.getUsername());
            throw new BusinessException("用户名只能包含中文和英文字母！");
        }

        // 唯一性校验（用户名+邮箱不能重复）
        try {
            logger.info("开始检查用户名是否已存在: " + user.getUsername());
            if (userDao.existsUsername(user.getUsername())) {
                logger.warning("注册失败：用户名" + user.getUsername() + "已存在");
                throw new BusinessException("该用户名已被注册！");
            }
            logger.info("用户名" + user.getUsername() + "可用");
            
            logger.info("开始检查邮箱是否已存在: " + user.getEmail());
            if (userDao.existsEmail(user.getEmail())) {
                logger.warning("注册失败：邮箱" + user.getEmail() + "已存在");
                throw new BusinessException("该邮箱已被注册！");
            }
            logger.info("邮箱" + user.getEmail() + "可用");
        } catch (SQLException e) {
            logger.log(Level.SEVERE, "注册失败：数据库查询异常", e);
            throw new BusinessException("注册失败：数据库查询异常！");
        }

        // 密码加密（使用工具类处理版本兼容性）
        logger.info("开始进行密码加密处理");
        String encryptedPwd = BCryptUtil.encrypt(user.getPassword());
        user.setPassword(encryptedPwd);
        logger.info("密码加密完成");

        // 插入数据库
        Connection conn = null;
        try {
            logger.info("准备将用户数据插入数据库");
            logger.info("插入前用户信息: " + user.toString());
            
            // 获取数据库连接用于事务控制
            conn = JdbcUtils.getConnection();
            logger.info("连接获取成功: " + conn);
            
            // 检查并记录连接的自动提交状态
            logger.info("当前连接自动提交状态: " + conn.getAutoCommit());
            
            // 关闭自动提交，手动控制事务
            conn.setAutoCommit(false);
            logger.info("已设置连接为手动提交事务");
            
            // 执行用户插入操作，传入当前连接进行事务控制
            userDao.insert(user, conn);
            logger.info("用户数据插入数据库成功！");
            
            // 手动提交事务
            conn.commit();
            logger.info("事务提交成功！");
            
            // 验证注册是否真的成功 - 使用同一个连接查询
            logger.info("开始验证注册结果：查询刚注册的用户");
            User registeredUser = userDao.findByUsername(user.getUsername(), conn);
            if (registeredUser != null) {
                logger.info("验证成功：用户已在数据库中存在，ID: " + registeredUser.getId());
            } else {
                logger.severe("验证失败：用户注册后在数据库中不存在！");
                throw new BusinessException("注册失败：用户数据未正确保存！");
            }
        } catch (SQLException e) {
            // 发生异常时回滚事务
            if (conn != null) {
                try {
                    conn.rollback();
                    logger.info("事务已回滚");
                } catch (SQLException ex) {
                    logger.log(Level.SEVERE, "事务回滚失败", ex);
                }
            }
            logger.log(Level.SEVERE, "注册失败：数据插入异常", e);
            throw new BusinessException("注册失败：数据插入异常！");
        } finally {
            // 恢复连接的自动提交状态并关闭连接
            if (conn != null) {
                try {
                    conn.setAutoCommit(true);
                    logger.info("已恢复连接的自动提交状态");
                } catch (SQLException ex) {
                    logger.log(Level.WARNING, "恢复自动提交状态失败", ex);
                }
                JdbcUtils.closeConnection(conn);
            }
        }
        
        logger.info("===== 用户注册处理完成 ====");
    }

    // 2. 登录功能
    public User login(String username, String password) throws BusinessException {
        // 基础参数校验
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            throw new BusinessException("用户名或密码不能为空！");
        }

        // 查询用户信息
        User user = null;
        try {
            user = userDao.findByUsername(username);
            if (user == null) {
                throw new BusinessException("用户名不存在！");
            }
        } catch (SQLException e) {
            throw new BusinessException("登录失败：数据库查询异常！");
        }

        // 校验账号状态（是否被禁用）
        if (user.getStatus() != 1) {
            throw new BusinessException("账号已被禁用，请联系管理员！");
        }

        // 校验密码（使用工具类处理版本兼容性）
        logger.info("开始密码验证");
        boolean passwordMatch = BCryptUtil.checkPassword(password, user.getPassword());
        
        if (!passwordMatch) {
            logger.warning("登录失败：密码错误或密码格式不兼容");
            // 检查是否是因为BCrypt版本不兼容
            if (!BCryptUtil.isValidHash(user.getPassword())) {
                throw new BusinessException("登录失败：密码格式不兼容，请联系管理员重置密码！");
            } else {
                throw new BusinessException("密码错误！");
            }
        }
        
        logger.info("密码验证成功");

        // 登录成功：返回用户信息（后续存入Session）
        return user;
    }

    // 3. 个人资料查询（根据用户ID）
    public User findUserById(Integer userId) throws BusinessException {
        logger.info("===== 开始查询用户资料 ====");
        logger.info("查询用户ID: " + userId);
        
        if (userId == null || userId <= 0) {
            logger.warning("查询用户资料失败：用户ID无效");
            throw new BusinessException("用户ID无效！");
        }

        try {
            User user = userDao.findById(userId);
            if (user == null) {
                logger.warning("查询失败：用户ID" + userId + "不存在");
                throw new BusinessException("用户不存在！");
            }
            logger.info("用户资料查询成功：" + user.getUsername());
            return user;
        } catch (SQLException e) {
            logger.log(Level.SEVERE, "查询用户资料异常", e);
            throw new BusinessException("查询用户资料失败！");
        }
    }
    
    // 4. 重置用户密码
    public void updatePassword(Integer userId, String newPassword) throws BusinessException {
        logger.info("===== 开始重置用户密码 ====");
        logger.info("重置密码的用户ID: " + userId);
        
        // 参数校验
        if (userId == null || userId <= 0) {
            logger.warning("重置密码失败：用户ID无效");
            throw new BusinessException("用户ID无效！");
        }
        if (StringUtils.isEmpty(newPassword) || newPassword.length() < 6) {
            logger.warning("重置密码失败：密码长度不足6位");
            throw new BusinessException("密码长度不能少于6位！");
        }
        
        // 密码加密
        logger.info("开始进行密码加密处理");
        String encryptedPwd = BCryptUtil.encrypt(newPassword);
        logger.info("密码加密完成");
        
        // 更新密码
        Connection conn = null;
        try {
            conn = JdbcUtils.getConnection();
            userDao.updatePassword(userId, encryptedPwd, conn);
            logger.info("用户密码重置成功");
        } catch (SQLException e) {
            logger.log(Level.SEVERE, "重置用户密码异常", e);
            throw new BusinessException("重置密码失败！" + e.getMessage());
        } finally {
            JdbcUtils.closeConnection(conn);
        }
        
        logger.info("===== 用户密码重置操作完成 ====");
    }

    // 4. 个人资料修改
    public void updateProfile(User user) throws BusinessException {
        // 基础参数校验
        if (user.getId() == null || user.getId() <= 0) {
            throw new BusinessException("用户ID无效！");
        }

        // 检查是否至少修改了一个字段
        boolean hasChanges = false;
        if (StringUtils.isNotEmpty(user.getNickname())) {
            hasChanges = true;
            // 邮箱唯一性校验（只有当邮箱有值且发生变化时才进行校验）
            try {
                if (StringUtils.isNotEmpty(user.getEmail()) && userDao.existsEmailExceptId(user.getEmail(), user.getId())) {
                    throw new BusinessException("该邮箱已被其他用户使用！");
                }
            } catch (SQLException e) {
                throw new BusinessException("修改失败：邮箱校验异常！");
            }
        }

        if (!hasChanges && StringUtils.isEmpty(user.getAvatar())) {
            throw new BusinessException("请至少修改一个字段！");
        }

        // 更新数据库
        try {
            userDao.updateProfile(user);
        } catch (SQLException e) {
            throw new BusinessException("修改失败：数据更新异常！");
        }
    }
}